﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Perceiveit.Xml
{
    /// <summary>
    /// A loosely typed conversion method set to change an object to its string representation and back again
    /// </summary>
    public interface IXConverter
    {
        /// <summary>
        /// Gets the Type that this IXConverter can convert to and from its string representations
        /// </summary>
        Type ConvertsType { get; }

        /// <summary>
        /// Converts the string representation to a object
        /// </summary>
        /// <param name="value">The string representation - can be null or empty</param>
        /// <returns>An object parsed from the string representation or null(default)</returns>
        object ObjectFromString(string value);

        /// <summary>
        /// Converts the object to a string representation
        /// </summary>
        /// <param name="value">The object to convert - can be null or default</param>
        /// <returns>The string representation of the object</returns>
        string ObjectToString(object value);
    }

    /// <summary>
    /// Defines a set of property cells that can be accessed by their XProperty 
    /// </summary>
    public interface IXPropertyBag
    {
        /// <summary>
        /// Gets the number of items in this bag
        /// </summary>
        int Count { get; }


        /// <summary>
        /// Attempts to retrieve an XPropertyCell for the provided 
        /// XProperty and returns true if a cell was found
        /// </summary>
        /// <param name="property">The XProperty to get the cell for</param>
        /// <param name="cell">An XProperty cell that contains both the associated XNode and the parsed value</param>
        /// <returns>True if this bag contained a corresponding XPropertyCell for the XProperty</returns>
        bool TryGetCell(XProperty property, out XPropertyCell cell);


        /// <summary>
        /// Sets the XPropertyCell value to the parameter for the specified XProperty
        /// </summary>
        /// <param name="property">The property to set</param>
        /// <param name="cell">The value to assign to this property</param>
        void SetCell(XProperty property, XPropertyCell cell);


        /// <summary>
        /// Removes the cell from the bag for the specified XProperty
        /// NOTE - this should not remove the referenced XNode from the underlying Xml
        /// </summary>
        /// <param name="property">The property to clear the cell for</param>
        void ClearCell(XProperty property);
    }


    /// <summary>
    /// Interface to define a method for deep cloning an object - copying all
    /// data, not just references to contained objects
    /// </summary>
    public interface IDeepCloneable : ICloneable
    {
        /// <summary>
        /// Returns a new instance of the specified object. This can be either a shallow or deep
        /// clone depending upon the value of the 'deep' parameter.
        /// </summary>
        /// <param name="deep"></param>
        /// <returns></returns>
        object Clone(bool deep);
    }

}
